/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fourbox.client;

import fourbox.Metafile;
import fourbox.server.Server;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author hartono
 */
public class ClientUploader implements Runnable {

    String contextPath;
    String host;
    int port;
    List queue;
       

    public ClientUploader(String contextPath, String host, int port, List queue) {
        this.contextPath = contextPath;
        this.host = host;
        this.port = port;
        this.queue = queue;
        System.out.println("Client uploader created");
    }

    public static void main(String args[]) throws FileNotFoundException, IOException {


        String workDir = "D:/Fourbox/";
        List queue = Collections.synchronizedList(new ArrayList());
        queue.add(Metafile.createMetafile(workDir, new File("D:/Fourbox/a.txt")));
//        queue.add(Metafile.createMetafile(new File("D:/tes.txt")));
//        queue.add(Metafile.createMetafile(new File("D:/a.pdf")));
        queue.add(Metafile.createMetafile(workDir, new File("D:/Fourbox/a/b/c")));

        ClientUploader sender = new ClientUploader(workDir, "localhost", Server.SERVER_DOWNLOAD_PORT, queue);
        Thread fileSenderThread = new Thread(sender);
        fileSenderThread.start();


    }

    @Override
    public void run() {
        System.out.println("Client Uploader : started..there are " + queue.size() + " file to upload");
        try {
            Socket clientSocket = new Socket(host, port);
            DataInputStream in = new DataInputStream(clientSocket.getInputStream());
            ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
            boolean wait = false;
            while (queue.size() > 0) {
                if (in.available() != 0) {
                    try {
                        byte[] msg = new byte[5];
                        System.out.println("Client Uploader : Receive ack " + in.available());
                        if (in.readInt() == 1) {
                            if (in.read() == 1) {
                                System.out.println("Client Uploader : ACK");
                                // if ack 
                                queue.remove(0);
                                wait = false;
                            } else {
                                System.out.println("Client Uploader : NAK");
                                wait = false;
                                break;
                            }
                        } else {
                            System.out.println("Client Uploader : unknown acknowledgement");
                        }
                    } catch (Exception e) {
                        System.out.println("Client Uploader : error parsing acknowledgment");
                        e.printStackTrace();
                    }
                } else {
                    if (!wait) {
                        Metafile headQueue = (Metafile) queue.get(0);
                        System.out.println("Client Uploader : Sending Metafile -> " + headQueue);

                        if (headQueue.status == Metafile.OK || headQueue.status == Metafile.NEW || headQueue.status == Metafile.UPDATED) {
                            File headFile = Metafile.createFileFromMetafileClient(contextPath, headQueue);
                            if (headFile.exists()) {
                                if (headFile.isFile()) {
                                    System.out.println("Client Uploader : "+headFile+" is file");
                                    // is file
                                    FileInputStream fis = new FileInputStream(headFile);
                                    out.writeInt(1);
                                    out.writeObject(headQueue);

                                    byte[] b = new byte[10];
                                    while (fis.available() > 0) {
                                        int len = fis.read(b);
                                        out.write(b, 0, len);
                                    }
                                    out.flush();
                                    System.out.println("Client Uploader : "+headFile+" content sent");
                                    
                                    wait = true;
                                    fis.close();
                                    try {
                                        System.out.println("Client Uploader : Sleep");
                                        Thread.sleep(100);
                                        System.out.println("Client Uploader : Wake");                                        
                                    } catch (InterruptedException ex) {
                                        Logger.getLogger(ClientUploader.class.getName()).log(Level.SEVERE, null, ex);
                                    }
                                    
                                } else {
                                    // is folder
                                    out.writeInt(1);
                                    out.writeObject(headQueue);
                                    out.flush();
                                    System.out.println("Client Uploader : "+headQueue+" folder send command issue");
                                    wait = true;
                                    try {
                                        System.out.println("Client Uploader : Sleep");
                                        Thread.sleep(100);
                                        System.out.println("Client Uploader : Wake");
                                    } catch (InterruptedException ex) {
                                        Logger.getLogger(ClientUploader.class.getName()).log(Level.SEVERE, null, ex);
                                    }
                                }
                            } else {
                                // not exist
                                System.out.println("Not exist " + headFile);
                                out.close();
                                in.close();
                                clientSocket.close();
                                break;
                            }
                        } else {
                            // delete
                            out.writeInt(1);
                            out.writeObject(headQueue);
                            out.flush();
                            wait = true;
                            System.out.println("Client Uploader : Delete msg "+headQueue);

                            try {
                                System.out.println("Client Uploader : Sleep");
                                Thread.sleep(100);
                                System.out.println("Client Uploader : Wake");
                            } catch (InterruptedException ex) {
                                Logger.getLogger(ClientUploader.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }


                    } else {
                        // not waiting                        
                    }
                }
            }

            out.close();
            in.close();
            clientSocket.close();


        } catch (UnknownHostException ex) {
            Logger.getLogger(ClientUploader.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ClientUploader.class.getName()).log(Level.SEVERE, null, ex);
        }
        System.out.println("Client Uploader : thread closed");
    }
}
